package com.pansoft.nfc.acs.activity;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import androidx.appcompat.app.AlertDialog;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;

import com.acs.bluetooth.Acr1255uj1Reader;
import com.acs.bluetooth.Acr3901us1Reader;
import com.acs.bluetooth.BluetoothReader;
import com.acs.bluetooth.BluetoothReaderGattCallback;
import com.acs.bluetooth.BluetoothReaderManager;
import com.airbnb.lottie.LottieAnimationView;
import com.clj.fastble.BleManager;
import com.clj.fastble.data.BleDevice;
import com.efounder.chat.utils.AESSecretUtil;
import com.efounder.chat.utils.CommonThreadPoolUtils;
import com.efounder.constant.EnvironmentVariable;
import com.efounder.http.EFHttpRequest;
import com.efounder.util.EnvSupportManager;
import com.efounder.util.ToastUtil;
import com.efounder.utils.EasyPermissionUtils;
import com.efounder.utils.ResStringUtil;
import com.pansoft.nfc.NfcAlertUtils;
import com.pansoft.nfc.NfcCommonUtils;
import com.pansoft.nfc.acs.ApduListManager;
import com.pansoft.nfc.mifare.Common;
import com.pansoft.openplanet.R;
import com.pansoft.openplanet.account.model.BtcBean;
import com.pansoft.openplanet.account.model.EthBean;
import com.pansoft.openplanet.account.util.BTCAccountGenerator;
import com.pansoft.openplanet.account.util.EthAccountGenerator;
import com.pansoft.openplanet.activity.BleBlutoothScanActivity;
import com.pansoft.openplanet.activity.TCBaseActivity;
import com.pansoft.openplanet.bean.Account;
import com.pansoft.openplanet.bean.CardBean;
import com.pansoft.openplanet.bean.CardWalletInfo;
import com.pansoft.openplanet.bean.CreateChildWalletBean;
import com.pansoft.openplanet.constant.IPAssetsConstant;
import com.pansoft.openplanet.constant.TalkChainConstant;
import com.pansoft.openplanet.db.AccountDao;
import com.pansoft.openplanet.db.CardDao;
import com.pansoft.openplanet.manager.ColdWalletManager;
import com.pansoft.openplanet.util.PrivateKeyUtils;
import com.pansoft.openplanet.util.TCAccountManager;
import com.pansoft.openplanet.widget.CommonPassWordAlertDialog;
import com.pansoft.openplanet.widget.TCLoadingDataView;
import com.utilcode.util.LogUtils;
import com.utilcode.util.TimeUtils;
import com.utilcode.util.ToastUtils;

import org.json.JSONObject;

import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import io.reactivex.disposables.Disposable;
import pl.droidsonroids.gif.GifDrawable;
import pl.droidsonroids.gif.GifImageView;
import pub.devrel.easypermissions.AfterPermissionGranted;

import static com.pansoft.nfc.NfcCommonUtils.getBlockByPosition;
import static com.pansoft.nfc.NfcCommonUtils.getChangePinHex;
import static com.pansoft.nfc.NfcCommonUtils.getInsertWalletPosition;
import static com.pansoft.nfc.NfcCommonUtils.getReadWalletPosition;
import static com.pansoft.nfc.acs.AcsBleManager.APDU_COMMAND_LOAD_AUTH;
import static com.pansoft.nfc.acs.AcsBleManager.DEFAULT_1255_MASTER_KEY;
import static com.pansoft.nfc.acs.AcsBleManager.getResponseString;
import static com.pansoft.nfc.acs.Utils.hexString2Bytes;
import static com.pansoft.openplanet.util.BTCMnemonicUtils.exportBtcMnemonics;

/**
 * @author wang
 * ACR1311 蓝牙读卡器 nfc 通信
 * 流程 检测权限--> 连接设备 --> 连接成功 --> 验证设备 -->验证成功 --> 检测卡片（Power on）-->
 * 连接卡片成功 --> 读写操作
 */

public class BleNfcMessageActivity extends TCBaseActivity implements View.OnClickListener {

    private static final String TAG = "BleNfcMessageActivity";
    /**读取所有扇区*/
    public static final int APDU_MODE_READ_ALL = 0;
    /**读取一个钱包，从标志位判断，是否是目标钱包，不是则继续往下一个钱包数据读取*/
    public static final int APDU_MODE_CHECK_UID = 1;
    /**写入所有扇区，覆盖，不足部分补0*/
    public static final int APDU_MODE_WRITE_COLD = 2;
    /**写入每个钱包前的标志数据，表示开始写入，但未完成。包括钱包数据的位置*/
    public static final int APDU_MODE_WRITE_START = 3;

    /**转换成热钱包后，清除卡片数据*/
    public static final int APDU_MODE_CONVERT_TO_HOT_CLEAR_CARD = 6;
    /**转换成热钱包，读取私钥恢复*/
    public static final int APDU_MODE_CONVERT_TO_HOT_READ_PRIV_KEY = 7;
    /**转账，读取私钥，返回*/
    public static final int APDU_MODE_READ_PRIVATE_KEY = 8;
    /** 添加卡片 */
    public static final int APDU_MODE_ADD_CARD = 9;
    /**重置PIN */
    public static final int APDU_MODE_RESET_PIN = 10;
    /** 修改PIN */
    public static final int APDU_MODE_CHANGE_PIN = 11;
    private TextView tvTitle;
    private TextView tvReconnect;
    private TextView tvStatus;
    private LottieAnimationView animationView;
    private GifImageView ivImage;

    private BleDevice bleDevice;

    private List<String> readApduList;
    private List<String> writeApduList;
    private int apduMode;
    private int createType;
    private int readCount = 0;
    private StringBuilder responseString = new StringBuilder();
    /** Detected reader. */
    private BluetoothReader mAcsBluetoothReader;
    /** ACS Bluetooth reader library. */
    private BluetoothReaderManager mAcsBluetoothReaderManager;
    private BluetoothReaderGattCallback mAcsGattCallback;
    private BluetoothGatt mAcsBluetoothGatt;

    private AccountDao accountDao;
    private Account account;
    private int chainId;
    /** 私钥， Eth是私钥，btc是助记词，eos是两个私钥 */
    private String generalPrivateKey;
    /** 需写入的地址*/
    private String address;
    /** 新建钱包的bean */
    private CreateChildWalletBean childWalletBean;
    /** 是否是新建钱包 */
    private boolean isNewCreateWallet = false;

    private String accountName;
    private String accountAvatar;

    private String keyStoreDir;

    /**
     * 卡片的PIN码
     */
    private String password;
    private String uid;
    private String cardType;
    private CardBean cardBean;
    private CardDao cardDao;
    private int position;
    private String positionString = "";
    private String[] positions;
    private List<CardWalletInfo> cardWalletInfoList;
    private String startString;
    private String coldWalletString;
    private String cardInfoString;
    private String changePinString;

    private TCAccountManager tcAccountManager;
    private ColdWalletManager coldWalletManager;

    /**
     * 冷热钱包转换，传入的是address
     *
     * @param context context
     * @param bleDevice 设备;
     * @param address   写入的地址
     * @param type      创建，转换，还是读取私钥
     */
    public static void start(Context context, BleDevice bleDevice, String address, int type) {
        Intent starter = new Intent(context, BleNfcMessageActivity.class);
        starter.putExtra("bleDevice", bleDevice);
        starter.putExtra("address", address);
        starter.putExtra("createType", type);
        context.startActivity(starter);
    }

    /**
     * 创建子钱包，传入的是CreateChildWalletBean
     *
     * @param context context
     * @param bleDevice 设备
     * @param childWalletBean 钱包bean
     */
    public static void start(Context context, BleDevice bleDevice, CreateChildWalletBean childWalletBean,
                             int type) {
        Intent starter = new Intent(context, BleNfcMessageActivity.class);
        starter.putExtra("bleDevice", bleDevice);
        starter.putExtra("childWalletBean", childWalletBean);
        starter.putExtra("createType", type);
        context.startActivity(starter);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.open_planet_activity_ble_message_all);
        initView();
        bleDevice = getIntent().getParcelableExtra("bleDevice");
        //方式，创建冷钱包，转换，转账，添加卡片，删除等
        createType = getIntent().getIntExtra("createType", BleBlutoothScanActivity.TYPE_CREATE_COLD_WALLET);
        cardDao = new CardDao(this);
        checkBltPermission();
        initData();
    }

    private void initView() {
        tvTitle = (TextView) findViewById(R.id.tv_title);
        tvStatus = (TextView) findViewById(R.id.tv_status);
        animationView = (LottieAnimationView) findViewById(R.id.animation_view);
        animationView.setImageAssetsFolder("ble/");
        ivImage = (GifImageView) findViewById(R.id.iv_image);
        tvReconnect = (TextView) findViewById(R.id.tv_save);
        tvReconnect.setOnClickListener(this);
    }

    private void initData() {
        tvReconnect.setText(R.string.common_text_device_reconnect);
        switch (createType) {
            case BleBlutoothScanActivity.TYPE_ADD_CARD:
                tvTitle.setText(R.string.open_planet_add_cards);
                break;
            case BleBlutoothScanActivity.TYPE_READ_PRIV_KEY:
                tvTitle.setText(R.string.open_planet_asset_transfer);
                initParams();
                break;
            case BleBlutoothScanActivity.TYPE_CREATE_COLD_WALLET:
                initParams();
                tvTitle.setText(R.string.op_create_cold_wallet);
                onNewCreatedWallet();
                break;
            case BleBlutoothScanActivity.TYPE_CONVERT_WALLET:
                initParams();
                //转换成冷钱包
                if (account.getAccountType() == Account.ACCOUNT_TYPE_COMMON) {
                    tvTitle.setText(R.string.op_convert_to_cold_wallet);
                    CommonThreadPoolUtils.execute(new Runnable() {
                        @Override
                        public void run() {
                            onConvertToCold();
                        }
                    });
                    //转换成热钱包
                } else if (account.getAccountType() == Account.ACCOUNT_TYPE_COLD) {
                    tvTitle.setText(R.string.op_convert_to_hot_wallet);
                }

                break;
            case BleBlutoothScanActivity.TYPE_DELETE_COLD_CHILD_WALLET:
                initParams();
                tvTitle.setText(R.string.open_planet_asset_ip_wallet_detail_delete_wallet);
                break;
            case BleBlutoothScanActivity.TYPE_CHANGE_PIN:
                tvTitle.setText(R.string.star_asset_card_change_password);
                break;
            case BleBlutoothScanActivity.TYPE_RESET_PIN:
                tvTitle.setText(R.string.star_asset_card_reset_PIN);
                break;
            default:
                break;
        }

        tcAccountManager = new TCAccountManager(this);
        coldWalletManager = new ColdWalletManager(this);
        showBleConnecting();
        initAcsDevice();
        connectAcsReader();
    }

    /**
     * 初始化涉及钱包的一些参数
     */
    private void initParams() {
        if (getIntent().getExtras() != null) {
            address = getIntent().getStringExtra("address");
            childWalletBean = (CreateChildWalletBean) getIntent().getExtras().get("childWalletBean");
        }
        if (address == null || "".equals(address)) {
            if (childWalletBean == null) {
                return;
            }
            address = childWalletBean.getWalletAddress();
        }
        accountDao = new AccountDao(this);
        account = accountDao.getAccount(address);
    }

    /**
     * 执行APDU指令
     * 成功则拼接返回的字符串
     * 失败则返回63 00h
     */
    private void setApduExecuteListener() {
        /* 指令执行的回调结果*/
        mAcsBluetoothReader
                .setOnResponseApduAvailableListener(new BluetoothReader.OnResponseApduAvailableListener() {

                    @Override
                    public void onResponseApduAvailable(
                            BluetoothReader bluetoothReader, final byte[] apdu,
                            final int errorCode) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (errorCode != BluetoothReader.ERROR_SUCCESS) {
                                    showNfcFail();
                                    return;
                                }
                                String response = getResponseString(apdu, errorCode);
                                Log.d(TAG, response);
                                if ("6300".equals(response.replace((" "), "").replace("\n", ""))) {
                                    //返回失败
                                    showNfcFail();
                                    responseString = new StringBuilder();
                                    readCount = 0;
                                    return;
                                }
                                responseString.append(response.replaceAll("90 00", ""));
                                //默认为APDU_MODE_CHECK_UID
                                if (apduMode == APDU_MODE_CHECK_UID) {
                                    //供电找到卡片后自动运行
                                    readApduList = ApduListManager.getUidPinSectorList();
                                    if (readCount < readApduList.size()) {
                                        transmitAPDU(readApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        String result = responseString.toString();
                                        result = result.replace((" "), "").replace("\n", "");
                                        onReadStartSector(result);
//                                        dismissLoading();
                                        responseString = new StringBuilder();
                                        readCount = 0;
                                    }
                                } else if (apduMode == APDU_MODE_READ_ALL) {
                                    //读取所有数据，并显示
                                    readApduList = ApduListManager.getReadApduList(positions);
                                    if (readCount < readApduList.size()) {
                                        transmitAPDU(readApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        try {
                                            ivImage.setVisibility(View.INVISIBLE);
//                                            tvResponse.setText(new String(hexString2Bytes(responseString.toString()), "UTF-8").trim());
                                            onHandleWalletInfo(positions, responseString.toString());
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
//                                        dismissLoading();
                                        responseString = new StringBuilder();
                                        readCount = 0;

                                    }
                                } else if (apduMode == APDU_MODE_WRITE_COLD) {
                                    //新建冷钱包
                                    //写入钱包数据
                                    int startBlock = getBlockByPosition(position);
                                    //1. 写入第一个扇区，地址
                                    writeApduList = ApduListManager.getWriteHexList(coldWalletString,
                                            startBlock, 15);
                                    if (readCount < writeApduList.size()) {
                                        transmitAPDU(writeApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        //更新start区块信息，将新的position加入
                                        int ver = 0;
                                        if (!"".equals(cardBean.getVersion())) {
                                            ver = Integer.valueOf(cardBean.getVersion()) + 1;
                                        }
                                        cardBean.setVersion(String.valueOf(ver));
                                        if (!"".equals(positionString)) {
                                            positionString = positionString.concat("," + position);
                                        } else {
                                            positionString = position + "";
                                        }
                                        Map<String, String> jsonMap = new HashMap<>();
                                        jsonMap.put("p", positionString);
                                        jsonMap.put("v", ver + "");
                                        final JSONObject jsonObject = new JSONObject(jsonMap);
                                        startString = ApduListManager.parseStartData(
                                                positionString, String.valueOf(ver));
                                        apduMode = APDU_MODE_WRITE_START;
                                        transmitAPDU(APDU_COMMAND_LOAD_AUTH);
//                                        dismissLoading();
                                        responseString = new StringBuilder();
                                        readCount = 0;
                                    }
                                } else if (apduMode == APDU_MODE_CONVERT_TO_HOT_READ_PRIV_KEY) {
                                    readApduList = ApduListManager.getReadApduList(positions);
                                    if (readCount < readApduList.size()) {
                                        transmitAPDU(readApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        try {
                                            onReadWalletAddress(new String(hexString2Bytes(responseString.toString()), "UTF-8").trim());
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
//                                        dismissLoading();
                                        responseString = new StringBuilder();
                                        readCount = 0;

                                    }
                                } else if (apduMode == APDU_MODE_CONVERT_TO_HOT_CLEAR_CARD) {
                                    writeApduList = ApduListManager.getWriteZero();
                                    if (readCount < writeApduList.size()) {
                                        transmitAPDU(writeApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        try {
                                            showConvertSuccess();
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }
//                                        dismissLoading();
                                        responseString = new StringBuilder();
                                        readCount = 0;
                                    }
                                } else if (apduMode == APDU_MODE_READ_PRIVATE_KEY) {
                                    readApduList = ApduListManager.getReadPriKeyList(position);
                                    if (readCount < readApduList.size()) {
                                        transmitAPDU(readApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        try {
                                            onReadPrivKey(responseString.toString());
                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }//                                        dismissLoading();
                                        responseString = new StringBuilder();
                                        readCount = 0;

                                    }
                                } else if (apduMode == APDU_MODE_WRITE_START) {
                                    writeApduList = ApduListManager.getWriteHexList(startString, 8, 3);
                                    if (readCount < writeApduList.size()) {
                                        transmitAPDU(writeApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        try {
                                            if (createType == BleBlutoothScanActivity.TYPE_ADD_CARD) {
                                                cardBean.setWalletInfoList(new ArrayList<CardWalletInfo>());
                                                cardBean.setEnable(true);
                                                cardDao.insertOrReplace(cardBean);
                                                addCardSuccess();
                                            } else if (createType == BleBlutoothScanActivity.TYPE_CONVERT_WALLET
                                                    && account.getAccountType() == Account.ACCOUNT_TYPE_COMMON) {
                                                //本地card数据库删除掉该钱包
                                                deleteWalletFromCardDb();
                                                NfcAlertUtils.showConvertSuccess(BleNfcMessageActivity.this);
                                            } else if (createType == BleBlutoothScanActivity.TYPE_DELETE_COLD_CHILD_WALLET) {
                                                deleteWalletFromCardDb();
                                                ToastUtils.showShort(R.string.common_text_delete_success);
                                                setResult(RESULT_OK);
                                                finish();
                                            } else {
                                                saveCardWallet();
                                                if (isNewCreateWallet) {
                                                    onWriteColdWalletSucceed(uid, cardInfoString);
                                                } else {
                                                    onConvertToColdWalletSucceed(cardInfoString);
                                                }
                                            }

                                        } catch (Exception e) {
                                            e.printStackTrace();
                                        }

//                                        dismissLoading();
                                        responseString = new StringBuilder();
                                        readCount = 0;
                                    }
                                } else if (apduMode == APDU_MODE_RESET_PIN) {
                                    writeApduList = ApduListManager.getWriteHexList(changePinString, 4, 3);
                                    if (readCount < writeApduList.size()) {
                                        transmitAPDU(writeApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        responseString = new StringBuilder();
                                        readCount = 0;
                                        ToastUtils.showShort(R.string.star_asset_pin_reset_to_000000);
                                        setResult(RESULT_OK);
                                        finish();
//                                        dismissLoading();
                                    }
                                } else if ((apduMode == APDU_MODE_CHANGE_PIN)) {
                                    writeApduList = ApduListManager.getWriteHexList(changePinString, 4, 3);
                                    if (readCount < writeApduList.size()) {
                                        transmitAPDU(writeApduList.get(readCount));
                                        readCount++;
                                    } else {
                                        responseString = new StringBuilder();
                                        readCount = 0;
                                        ToastUtils.showShort(R.string.common_text_pw_change_pw_success);
                                        setResult(RESULT_OK);
                                        finish();
//                                        dismissLoading();
                                    }
                                }

                            }
                        });
                    }

                });
    }

    /**
     * 发送指令
     *
     * @param hexCommand 十六进制指令
     */
    private void transmitAPDU(String hexCommand) {
        /* Check for detected reader. */
        Log.w(TAG, hexCommand);
        if (mAcsBluetoothReader == null) {
            showNfcFail();
            ToastUtils.showShort("card_reader_not_ready");
            return;
        }
        /* Retrieve APDU command from edit box. */
        byte[] apduCommand = hexString2Bytes(hexCommand);
        if (apduCommand != null && apduCommand.length > 0) {
            /* Transmit APDU command. */
            if (!mAcsBluetoothReader.transmitApdu(apduCommand)) {
                showNfcFail();
                ToastUtils.showShort("card_reader_not_ready");
            }
        } else {
            showNfcFail();
            ToastUtils.showShort("Character format error!");
        }
    }

    /**
     * 写卡成功后设置本地数据库冷钱包
     * 新建钱包，用bean里的数据，上传服务器
     * 转换钱包，使用file生成私钥等信息，再修改服务器信息
     */
    private void onWriteColdWalletSucceed(final String uid, final String cardInfo) {
        //1. 上传服务器成功后
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                if (tcAccountManager.addCardWalletToServer(uid, cardInfo, EnvironmentVariable.getProperty("tc_ethAddress"),
                        address, accountAvatar, accountName, chainId + "", position + "")) {
                    //上传成功
                    //2. 操作本地数据库
                    try {
                        coldWalletManager.onChangeLocalWallet(account);
                    } catch (Exception e) {
                        e.printStackTrace();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                showNfcFail();
                            }
                        });
                    }
                    //3.成功之后再写卡，加入完成标志位
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            showCreateWalletSuccess();
                        }
                    });
                } else {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            showNfcFail();
                        }
                    });
                }
            }
        });
    }

    /**
     * 转换冷钱包，写卡成功后设置本地数据库冷钱包
     */
    private void onConvertToColdWalletSucceed(final String cardInfo) {
        //1. 上传服务器成功后
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                if (tcAccountManager.convertCardWallet(EnvironmentVariable.getProperty("tc_ethAddress"), uid,
                        chainId + "", "3", address, position + "",
                        cardInfo, "", "")) {

                    //上传成功
                    //2. 操作本地数据库
                    try {
                        coldWalletManager.onChangeLocalWallet(account);
                    } catch (Exception e) {
                        e.printStackTrace();
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                showNfcFail();
                            }
                        });
                    }
                    //3.成功之后再写卡，加入完成标志位
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            NfcAlertUtils.showConvertSuccess(BleNfcMessageActivity.this);
                        }
                    });
                } else {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            showNfcFail();
                        }
                    });
                }
            }
        });
    }

    /**
     * 处理新建钱包
     */
    private void onNewCreatedWallet() {
        chainId = childWalletBean.getChainId();
        address = childWalletBean.getWalletAddress();
        if (chainId == IPAssetsConstant.CHAIN_ID_ETH) {
            generalPrivateKey = TCAccountManager.convertTo16Radix(childWalletBean.getPrivateKey());
        } else if (chainId == IPAssetsConstant.CHAIN_ID_BTC) {
            generalPrivateKey = childWalletBean.getMnemonic();
        } else if (chainId == IPAssetsConstant.CHAIN_ID_EOS) {
            generalPrivateKey = childWalletBean.getPrivateKey() + "|"
                    + childWalletBean.getEosActivePriKey();
        }
        accountAvatar = childWalletBean.getWalletAvatar();
        accountName = childWalletBean.getWalletName();
    }

    /**
     * 处理转换钱包，从地址，本地钱包得到私钥
     */
    private void onConvertToCold() {
        if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.ETH.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_ETH;
            generalPrivateKey = PrivateKeyUtils.exportPrivateKey(account.getFileName(), "");
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.BTC.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_BTC;
            generalPrivateKey = exportBtcMnemonics(account.getFileName());
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.EOS.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_EOS;
            generalPrivateKey = PrivateKeyUtils.exportEosPrivateKey(account.getSecretPrivateKey(), "")
                    + "|" + PrivateKeyUtils.exportEosPrivateKey(account.getEosActivePriKey(), "");
        }
        accountAvatar = account.getAccountAvatar();
        accountName = account.getAcccountName();
    }

    /**
     * 处理转换钱包，从nfc卡上私钥恢复本地文件，上传服务器，修改数据库，nfc卡置0
     */
    private void onConvertToHot() {
        //创建目录
        keyStoreDir = TalkChainConstant.getChildAccountFilePath(this) + File.separator + EnvironmentVariable.getUserName();
        File file = new File(keyStoreDir);
        if (!file.exists()) {
            file.mkdirs();
        }
        if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.ETH.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_ETH;
            dealDeleteCardInfo();
            restoreEth();
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.BTC.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_BTC;
            dealDeleteCardInfo();
            restoreBtc();
        } else if (account.getBlockChainName().equals(IPAssetsConstant.ChainEnum.EOS.chainName)) {
            chainId = IPAssetsConstant.CHAIN_ID_EOS;
        }
    }

    private void restoreEth() {
        Disposable disposable = EthAccountGenerator.recoverAccountByPrivateKey(keyStoreDir,
                generalPrivateKey, new EthAccountGenerator.GeneratorListener() {
                    @Override
                    public void generatorSuccess(final EthBean ethBean) {
                        //生成的账户放到服务器
                        CommonThreadPoolUtils.execute(new Runnable() {
                            @Override
                            public void run() {
                                String secretPrivateKey = TCAccountManager.encryptByMainPrivKey(
                                        TCAccountManager.convertTo16Radix(generalPrivateKey));
                                if (tcAccountManager.convertCardWallet(EnvironmentVariable.getProperty("tc_ethAddress"), uid,
                                        chainId + "", "1", address, position + "",
                                        cardInfoString, "", secretPrivateKey)) {

                                    //上传成功
                                    //2. 操作本地数据库
                                    account.setFileName(ethBean.getKeyStoreFilePath());
                                    account.setAccountType(Account.ACCOUNT_TYPE_COMMON);
                                    accountDao.insertOrReplace(account);

                                    //不需要清零，start区块的position删除掉即可
                                    dealDeleteCardInfo();
                                    deleteStartPosition(cardInfoString);
                                } else {
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            showNfcFail();
                                        }
                                    });
                                }
                            }
                        });
                    }

                    @Override
                    public void generatorFail() {
                        showNfcFail();
                    }
                });
        addDisposable(disposable);

    }

    private void restoreBtc() {
        Disposable disposable = BTCAccountGenerator.recoverBtcAccountByMnemoric(keyStoreDir,
                generalPrivateKey, new BTCAccountGenerator.GeneratorListener() {
                    @Override
                    public void generatorSuccess(final BtcBean btcBean) {
                        //生成的账户放到服务器
                        CommonThreadPoolUtils.execute(new Runnable() {
                            @Override
                            public void run() {
                                String secretPrivateKey = TCAccountManager.encryptByMainPrivKey(
                                        TCAccountManager.convertTo16Radix(generalPrivateKey));
                                if (tcAccountManager.convertCardWallet(EnvironmentVariable.getProperty("tc_ethAddress"), uid,
                                        chainId + "", "1", address, position + "",
                                        cardInfoString, secretPrivateKey, "")) {

                                    //上传成功
                                    //2. 操作本地数据库
                                    if (EnvSupportManager.isSupportHDWallet()) {
                                        account.setHdBtcXpub(btcBean.getHdBtcXpub());
                                        account.setHdBtcMaxChildIndex(btcBean.getHdBtcMaxChildIndex());
                                        account.setHdBtcCurrentChildAddress(btcBean.getHdBtcCurrentChildAddress());
                                    }
                                    account.setFileName(btcBean.getKeyStoreFilePath());
                                    account.setAccountType(Account.ACCOUNT_TYPE_COMMON);
                                    account.setCreateTime(TimeUtils.getNowString());
                                    account.setSecretMnemonic(btcBean.getSecretMnemonic());
                                    accountDao.insertOrReplace(account);
                                    //不需要清零，start区块的position删除掉即可
                                    dealDeleteCardInfo();
                                    deleteStartPosition(cardInfoString);
                                } else {
                                    runOnUiThread(new Runnable() {
                                        @Override
                                        public void run() {
                                            showNfcFail();
                                        }
                                    });
                                }
                            }
                        });
                    }

                    @Override
                    public void generatorFail() {
                        showNfcFail();
                    }
                });
        addDisposable(disposable);
    }

    private void deleteStartPosition(String cardInfo) {
        apduMode = APDU_MODE_WRITE_START;
        transmitAPDU(APDU_COMMAND_LOAD_AUTH);
    }

    private void dealDeleteCardInfo() {
        int ver = 0;
        if (!"".equals(cardBean.getVersion())) {
            ver = Integer.valueOf(cardBean.getVersion()) + 1;
        }
        cardBean.setVersion(String.valueOf(ver));
        if (positions.length < 1) {
            return;
        }
        position = getReadWalletPosition(getIntent().getStringExtra("address"), cardWalletInfoList);
        StringBuilder sb = new StringBuilder();
        for (String s :
                positions) {
            if (Integer.valueOf(s) != position) {
                if (sb.length() > 0) {
                    sb.append(",");
                }
                sb.append(s);
            }
        }
        startString = ApduListManager.parseStartData(
                sb.toString(), String.valueOf(ver));
        Map<String, String> jsonMap = new HashMap<>();
        jsonMap.put("p", sb.toString());
        jsonMap.put("v", ver + "");
        JSONObject jsonObject = new JSONObject(jsonMap);
        cardInfoString = jsonObject.toString();
    }

    /**
     * 从card表中删除钱包
     */
    private void deleteWalletFromCardDb() {
        List<CardWalletInfo> cardWalletInfos = new ArrayList<>();
        for (CardWalletInfo c :
                cardWalletInfoList) {
            if (c.getInCardPosition() != position) {
                cardWalletInfos.add(c);
            }
        }
        cardBean.setWalletInfoList(cardWalletInfos);
        cardBean.setEnable(true);
        cardDao.insertOrReplace(cardBean);
    }

    /**
     * 转换热钱包，读取nfc钱包数据，找出相符合的地址，读取私钥，恢复
     *
     * @param response 钱包数据
     */
    private void onReadWalletAddress(String response) {
        try {
            JSONObject jsonObject = new JSONObject(response);
            String addrJson = jsonObject.optString("addr").trim();
            if (addrJson.equals(address)) {
                generalPrivateKey = jsonObject.optString("privkey").trim();
                onConvertToHot();
            } else {
                showWrongCard();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 处理第0扇区第1扇区的数据，uid和pin码
     * 秘钥验证成功后处理cardInfo数据
     *
     * @param readContent 读取到的数据， 0扇区和1扇区
     */
    private void onReadStartSector(final String readContent) {
        try {
            if (!NfcCommonUtils.handleUidStartData(this, readContent)) {
                return;
            }
            uid = readContent.substring(32, 64);
            uid = new String(Common.hexStringToByteArray(uid), StandardCharsets.UTF_8).trim();
            cardType = readContent.substring(36, 40);
            cardType = new String(Common.hexStringToByteArray(cardType), StandardCharsets.UTF_8).trim();
            //替换掉前面的0
            cardType = cardType.replaceAll("^(0+)", "");
            cardBean = cardDao.getCardBean(uid);

            //读取1扇区，存有PIN密码，使用AES加密之后的
            String password = readContent.substring(96, 192);
            password = NfcCommonUtils.handleSecretKeyData(password);
            if (createType == BleBlutoothScanActivity.TYPE_CHANGE_PIN) {
                if (!uid.equals(getIntent().getStringExtra("cardNo"))) {
                    ToastUtils.showShort(R.string.star_asset_card_no_wrong);
                    setResult(RESULT_CANCELED);
                    finish();
                    return;
                } else if (!password.equals(getIntent().getStringExtra("rawPass"))) {
                    ToastUtils.showShort(R.string.common_text_raw_pw_wrong);
                    setResult(RESULT_CANCELED);
                    finish();
                    return;
                }
                onTransactionBegin();
            } else if (createType == BleBlutoothScanActivity.TYPE_RESET_PIN) {
                onTransactionBegin();
            } else {
                CommonPassWordAlertDialog commonPassWordAlertDialog = new CommonPassWordAlertDialog(this,
                        ResStringUtil.getString(R.string.star_asset_card_pin), password, new CommonPassWordAlertDialog.OnEnterClick() {
                    @Override
                    public void passVerifySuccess(String passWord) {
                        onDealCardInfo(readContent);
                    }
                });
                commonPassWordAlertDialog.show();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void onDealCardInfo(String startContent) {
        String cardInfo = startContent.substring(192, 288);
        cardInfo = new String(Common.hexStringToByteArray(cardInfo), StandardCharsets.UTF_8).trim();
        try {
            JSONObject jsonObject = new JSONObject(cardInfo);
            positionString = jsonObject.optString("p");
            positions = positionString.split(",");
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (createType == BleBlutoothScanActivity.TYPE_DELETE_COLD_CHILD_WALLET) {
            onTransactionBegin();
        } else {
            onAddCard(uid, cardType, cardInfo);
        }
    }

    public void onAddCard(final String uid, final String type, final String startResponse) {
        if (cardBean == null) {
            //本地无此卡，添加
            //添加卡片到服务器
            CommonThreadPoolUtils.execute(new Runnable() {
                @Override
                public void run() {
                    if (tcAccountManager.addCardToServer(uid, EnvironmentVariable.getProperty("tc_ethAddress"))) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                dealCardData(uid, type, startResponse, false);
                            }
                        });
                    } else {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                NfcAlertUtils.showNfcFailAlert(BleNfcMessageActivity.this);
                            }
                        });
                    }
                }
            });
        } else {
            //已经绑卡
            dealCardData(uid, type, startResponse, true);
        }

    }

    private void dealCardData(String uid, String type, String startResponse, boolean isAdded) {
        try {
            if (cardBean == null) {
                cardBean = new CardBean();
                cardBean.setUid(uid);
                cardBean.setCardType(type);
            }
            if ("".equals(startResponse)) {
                //空卡
                if (isAdded) {
                    //卡片没数据了，但是本地卡片还有，除了删除本地卡片数据库，还要删除Account数据库的
                    List<CardWalletInfo> cardWalletInfoList = cardBean.getWalletInfoList();
                    if (cardWalletInfoList != null && cardWalletInfoList.size() > 0) {
                        for (int i = 0; i < cardWalletInfoList.size(); i++) {
                            Account account = accountDao.getAccount(cardWalletInfoList.get(i).getAddress());
                            if (account != null) {
                                account.setEnable(false);
                                accountDao.insertOrReplace(account);
                            }
                        }
                    }
                }
                //更新start区块信息，将新的position加入
                int ver = 0;
                cardBean.setVersion(String.valueOf(ver));
                startString = ApduListManager.parseStartData(
                        "", String.valueOf(ver));
                apduMode = APDU_MODE_WRITE_START;
                transmitAPDU(APDU_COMMAND_LOAD_AUTH);
                return;
            }

            JSONObject jsonObject = new JSONObject(startResponse);
            String version = jsonObject.optString("v");
            //读取钱包位置
            String[] rawPositions = jsonObject.optString("p").split(",");
            String[] positions;
            //之前写入有错误，这里进行改正
            if (rawPositions.length > 0 && "".equals(rawPositions[0])) {
                positions = new String[rawPositions.length - 1];
                //之前写入一个空字符, 这里去掉
                System.arraycopy(rawPositions, 1, positions, 0, rawPositions.length - 1);
//                for (int i = 0; i < rawPositions.length; i++) {
//                    positions[i] = rawPositions[i + 1];
//                }
            } else {
                positions = rawPositions;
            }

            if (isAdded) {
//                if (!"".equals(version) && !version.equals(cardBean.getVersion())) {
                //卡片已添加，但是内容不一致，需更新本地数据库内容
//                if ("".equals(cardBean.getVersion()) || "0".equals(cardBean.getVersion())) {
                //本地无数据，可直接读卡复制
                //读取钱包
//                    readContent(positions, cardBean);
//                } else {
//                    //判断内容差距，选择性复制或删除
//                }
//                    return;
//                }
                addCardAlready();
                return;
            }
            if (positions.length <= 0) {
                //空卡
                cardBean.setVersion(version);
                cardBean.setWalletInfoList(new ArrayList<CardWalletInfo>());
                cardBean.setEnable(true);
                cardDao.insertOrReplace(cardBean);
                addCardSuccess();
            } else {
                //读取钱包
                apduMode = APDU_MODE_READ_ALL;
                transmitAPDU(APDU_COMMAND_LOAD_AUTH);
            }
        } catch (Exception e) {
            e.printStackTrace();
            showNfcFail();
        }
    }

    private void addCardSuccess() {
        if (createType == BleBlutoothScanActivity.TYPE_ADD_CARD) {
            ToastUtils.showShort(R.string.open_planet_add_card_success);
            setResult(RESULT_OK);
            finish();
        } else {
            //添加卡片成功，继续进行读写卡等操作
            onTransactionBegin();
        }
    }

    private void addCardAlready() {
        if (createType == BleBlutoothScanActivity.TYPE_ADD_CARD) {
            ToastUtils.showShort(R.string.open_planet_card_already_added);
            setResult(RESULT_OK);
            finish();
        } else {
            //添加卡片成功，继续进行读写卡等操作
            onTransactionBegin();
        }
    }

    /**
     * 开始处理业务，转账，转冷，转热等
     */
    private void onTransactionBegin() {
        if (cardBean == null) {
            showNfcFail();
            return;
        }
        cardWalletInfoList = cardBean.getWalletInfoList();
        if (cardWalletInfoList.size() > 0) {
            //已存在钱包
            //找到需要写入钱包的位置
            position = getInsertWalletPosition(40, cardWalletInfoList);
            if (createType == BleBlutoothScanActivity.TYPE_CREATE_COLD_WALLET ||
                    (createType == BleBlutoothScanActivity.TYPE_CONVERT_WALLET && account.getAccountType() == Account.ACCOUNT_TYPE_COMMON)) {
                //新建冷钱包或转换成冷钱包
                showNfcWriting();
                convertToCold();
            } else if (createType == BleBlutoothScanActivity.TYPE_READ_PRIV_KEY ||
                    createType == BleBlutoothScanActivity.TYPE_CONVERT_WALLET && account.getAccountType() == Account.ACCOUNT_TYPE_COLD) {
                //转账，读私钥
                showNfcReading();
                //传输数据
                position = getReadWalletPosition(address, cardWalletInfoList);
                apduMode = APDU_MODE_READ_PRIVATE_KEY;
                transmitAPDU(APDU_COMMAND_LOAD_AUTH);
            } else if (createType == BleBlutoothScanActivity.TYPE_CHANGE_PIN) {
                showNfcWriting();
                String newPass = getIntent().getStringExtra("newPass");
                apduMode = APDU_MODE_CHANGE_PIN;
                changePIN(newPass);
            } else if (createType == BleBlutoothScanActivity.TYPE_RESET_PIN) {
                showNfcWriting();
                apduMode = APDU_MODE_RESET_PIN;
                changePIN("000000");
            } else if (createType == BleBlutoothScanActivity.TYPE_DELETE_COLD_CHILD_WALLET) {
                deleteWalletFromServer();
            }
        } else {
            //空卡
            //可以写入钱包
            //创建冷钱
            if (createType == BleBlutoothScanActivity.TYPE_CREATE_COLD_WALLET ||
                    (createType == BleBlutoothScanActivity.TYPE_CONVERT_WALLET && account.getAccountType() == Account.ACCOUNT_TYPE_COMMON)) {
                //新建冷钱包或转换成冷钱包
                showNfcWriting();
                convertToCold();
            } else {
                showEmptyCard();
            }
        }
    }

    private void changePIN(String password) {
        changePinString = getChangePinHex(password);
        transmitAPDU(APDU_COMMAND_LOAD_AUTH);
    }

    /**
     * 将钱包删除
     */
    private void deleteWalletFromServer() {
        try {
            //卡号
            if (!uid.equals(getIntent().getStringExtra("cardNo"))) {
                showWrongCard();
                return;
            }
            dealDeleteCardInfo();
            cardBean = cardDao.getCardBean(uid);
            cardWalletInfoList = cardBean.getWalletInfoList();
            JSONObject jsonObject = new JSONObject(cardInfoString);
            positionString = jsonObject.optString("p");
            positions = positionString.split(",");
        } catch (Exception e) {
            e.printStackTrace();
            showNfcFail();
            return;
        }
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                deleteFromServer();
            }
        });
    }

    private void deleteFromServer() {
        final AccountDao accountDao = new AccountDao(this);
        final Account account = accountDao.getAccount(getIntent().getStringExtra("address"));
        if (account == null) {
            //仅本地
            deleteStartPosition(cardInfoString);
            return;
        }
        if (new TCAccountManager(this).deleteCardWallet(account.getAddress(), cardBean.getUid(),
                cardInfoString)) {
            accountDao.delete(account.getAddress());
            deleteStartPosition(cardInfoString);
        } else {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    ToastUtil.showToast(BleNfcMessageActivity.this,
                            ResStringUtil.getString(R.string.common_text_delete_fails));
                }
            });
        }
    }

    private void convertToCold() {
        showNfcWriting();
        if (generalPrivateKey == null || "".equals(generalPrivateKey) || "".equals(address)) {
            showNfcFail();
            return;
        }
        CommonThreadPoolUtils.execute(new Runnable() {
            @Override
            public void run() {
                coldWalletString = ApduListManager.parseWalletData(chainId + "", address, generalPrivateKey);
                int ver = 0;
                if (!"".equals(cardBean.getVersion())) {
                    ver = Integer.valueOf(cardBean.getVersion()) + 1;
                }
                cardBean.setVersion(String.valueOf(ver));
                if (!"".equals(positionString)) {
                    positionString = positionString.concat("," + position);
                } else {
                    positionString = position + "";
                }
                Map<String, String> jsonMap = new HashMap<>();
                jsonMap.put("p", positionString);
                jsonMap.put("v", ver + "");
                final JSONObject jsonObject = new JSONObject(jsonMap);
                cardInfoString = jsonObject.toString();
                apduMode = APDU_MODE_WRITE_COLD;
                transmitAPDU(APDU_COMMAND_LOAD_AUTH);

            }
        });
    }

    /**
     * 处理钱包数据
     *
     * @param positions 钱包在卡上的位置
     * @param response  钱包数据
     */
    private void onHandleWalletInfo(String[] positions, String response) {
        //data处理，16进制，每32个字符一行，每15行是一个钱包，分成钱包，每32 X 15个字符一组
        String[] data = response.split("(?<=\\G............................................" +
                "...................................................................................." +
                "................................................................................................" +
                "................................................................................................" +
                "................................................................................................" +
                "................................................................)", 0);
        NfcCommonUtils.handleCardWalletData(this, positions, data, cardBean);
        cardDao.insertOrReplace(cardBean);
        addCardSuccess();
    }

    /**
     * 处理读取秘钥
     *
     * @param response
     */
    private void onReadPrivKey(String response) {
        try {
            response = response.replace((" "), "").replace("\n", "");
            //长度+chainId+长度+addr+长度+privateKey
            //第3、4位是chainId
            String chainId = new String(Common.hexStringToByteArray(response.substring(2, 4)),
                    StandardCharsets.UTF_8).trim();
            //5、6位是地址长度
            int addrLength = Integer.parseInt(response.substring(4, 6), 16);
            //取地址
            String addr = new String(Common.hexStringToByteArray(response.substring(6, 6 + addrLength)),
                    StandardCharsets.UTF_8).trim();
            //私钥长度
            int privateKeyLength = Integer.parseInt(response.substring(6 + addrLength, 8 + addrLength), 16);
            //取私钥
            String encryptPrivateKey = new String(Common.hexStringToByteArray(response.substring(8 + addrLength,
                    8 + addrLength + privateKeyLength)), StandardCharsets.UTF_8).trim();
            AESSecretUtil aesSecretUtil = new AESSecretUtil(Common.NFC_WALLET_SECRET_KEY);
            String privateKey = aesSecretUtil.decrypt(encryptPrivateKey);
            if (addr.equals(address)) {
                generalPrivateKey = privateKey;
                if (createType == BleBlutoothScanActivity.TYPE_READ_PRIV_KEY) {
                    Intent intent = new Intent();
                    intent.putExtra("privateKey", generalPrivateKey);
                    setResult(RESULT_OK, intent);
                    finish();
                } else {
                    onConvertToHot();
                }
            } else {
                showWrongCard();
            }
        } catch (Exception e) {
            e.printStackTrace();
            showNfcFail();
        }
    }

    /**
     * 保存钱包到card表
     */
    private void saveCardWallet() {
        CardWalletInfo cardWalletInfo = new CardWalletInfo();
        cardWalletInfo.setInCardPosition(position);
        cardWalletInfo.setChainId(chainId);
        cardWalletInfo.setAddress(address);
        cardWalletInfo.setWalletAvatar(accountAvatar);
        cardWalletInfo.setWalletName(accountName);
        cardWalletInfoList.add(cardWalletInfo);
        cardBean.setWalletInfoList(cardWalletInfoList);
        cardBean.setEnable(true);
        cardDao.insertOrReplace(cardBean);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        EFHttpRequest.cancelRequest("TCAccountManager");
        dispose();
        disconnectReader();
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        if (id == R.id.iv_back) {
            finish();
        } else if (id == R.id.btn_write) {

        } else if (id == R.id.tv_save) {
            //重连
            connectAcsReader();
        }
    }

    /**
     * 连接蓝牙设备
     */
    private void showBleConnecting() {
        tvStatus.setText(R.string.common_text_device_connecting);
//        showLoading(R.string.common_text_device_connecting);
        tvReconnect.setVisibility(View.GONE);
        animationView.setVisibility(View.VISIBLE);
        ivImage.setVisibility(View.GONE);
        animationView.setAnimation("ble/ble_nfc_read_write.json");
        animationView.playAnimation();
    }

    /**
     * 连接蓝牙设备失败
     */
    private void showBleConnectFail() {
        //        dismissLoading();
        TCLoadingDataView.dismiss();
        tvStatus.setText(R.string.common_text_bluetooth_connect_fail);
        tvReconnect.setVisibility(View.VISIBLE);
        //        ToastUtil.showToast(BleNfcMessageActivity.this, R.string.common_text_bluetooth_connect_fail);
        try {
            animationView.setVisibility(View.GONE);
            ivImage.setVisibility(View.VISIBLE);
            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_fail);
            gifDrawable.setLoopCount(1);
            ivImage.setImageDrawable(gifDrawable);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接卡片
     */
    private void showNfcConnecting() {
        tvStatus.setText(R.string.op_put_card);
        try {
            animationView.setVisibility(View.VISIBLE);
            ivImage.setVisibility(View.GONE);
            animationView.setAnimation("ble/ble_nfc_connecting.json");
            animationView.playAnimation();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接卡片失败
     */
    private void showNfcConnectFail() {
        TCLoadingDataView.dismiss();
        tvStatus.setText(R.string.op_read_card_fail_put_again);
        //        dismissLoading();
        tvReconnect.setVisibility(View.VISIBLE);
        ToastUtil.showToast(BleNfcMessageActivity.this, R.string.common_text_bluetooth_connect_fail);
        try {
            animationView.setVisibility(View.GONE);
            ivImage.setVisibility(View.VISIBLE);
            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_fail);
            gifDrawable.setLoopCount(1);
            ivImage.setImageDrawable(gifDrawable);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接卡片成功
     */
    private void showNfcConnectSuccess() {
        tvStatus.setText(R.string.op_connect_card_success);
        try {
            animationView.setVisibility(View.GONE);
            ivImage.setVisibility(View.VISIBLE);
            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_success);
            gifDrawable.setLoopCount(1);
            ivImage.setImageDrawable(gifDrawable);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写卡
     */
    private void showNfcWriting() {
        tvStatus.setText(R.string.op_card_transmitting_data);
        animationView.setVisibility(View.VISIBLE);
        ivImage.setVisibility(View.GONE);
        animationView.setAnimation("ble/ble_nfc_read_write.json");
        animationView.playAnimation();
    }

    /**
     * 读卡
     */
    private void showNfcReading() {
        tvStatus.setText(R.string.op_card_transmitting_data);
        animationView.setVisibility(View.VISIBLE);
        ivImage.setVisibility(View.GONE);
        animationView.setAnimation("ble/ble_nfc_read_write.json");
        animationView.playAnimation();
    }

    /**
     * 卡片操作失败
     */
    private void showNfcFail() {
        TCLoadingDataView.dismiss();
        tvStatus.setText(R.string.op_sth_wrong_put_card_again);
        try {
            animationView.setVisibility(View.GONE);
            ivImage.setVisibility(View.VISIBLE);
            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_fail);
            gifDrawable.setLoopCount(1);
            ivImage.setImageDrawable(gifDrawable);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (isFinishing()) {
            return;
        }
        new AlertDialog.Builder(this).setTitle(R.string.common_text_hint)
                .setMessage(R.string.op_sth_wrong_put_card_again)
                .setCancelable(false)
                .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        showNfcConnecting();
                        powerOnCard();
                    }
                })
                .setNegativeButton(R.string.common_text_cancel, null)
                .create().show();
    }

    private void showEmptyCard() {
        TCLoadingDataView.dismiss();
        tvStatus.setText(R.string.op_no_data_put_card_again);
        try {
            animationView.setVisibility(View.GONE);
            ivImage.setVisibility(View.VISIBLE);
            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_fail);
            gifDrawable.setLoopCount(1);
            ivImage.setImageDrawable(gifDrawable);
        } catch (Exception e) {
            e.printStackTrace();
        }
        new AlertDialog.Builder(this).setTitle(R.string.common_text_hint)
                .setMessage(R.string.op_no_data_put_card_again)
                .setCancelable(false)
                .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        showNfcConnecting();
                        powerOnCard();
                    }
                })
                .setNegativeButton(R.string.common_text_cancel, null)
                .create().show();
    }

    /**
     * 卡片操作失败
     */
    private void showWrongCard() {
        TCLoadingDataView.dismiss();
        tvStatus.setText(R.string.op_incorrect_address_put_card_again);
        try {
            animationView.setVisibility(View.GONE);
            ivImage.setVisibility(View.VISIBLE);
            GifDrawable gifDrawable = new GifDrawable(getResources(), R.drawable.ble_nfc_connect_fail);
            gifDrawable.setLoopCount(1);
            ivImage.setImageDrawable(gifDrawable);
        } catch (Exception e) {
            e.printStackTrace();
        }
        new AlertDialog.Builder(this).setTitle(R.string.common_text_hint)
                .setMessage(R.string.op_incorrect_address_put_card_again)
                .setCancelable(false)
                .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        showNfcConnecting();
                        powerOnCard();
                    }
                })
                .setNegativeButton(R.string.common_text_cancel, null)
                .create().show();
    }

    /**
     * 写入完成标志位，标志钱包已完整写入
     */
    private void showCreateWalletSuccess() {
        //3.成功之后再写卡，加入完成标志位
        TCLoadingDataView.dismiss();
        new AlertDialog.Builder(this).setTitle(R.string.open_planet_create_success)
                .setCancelable(false)
                .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finishAffinity();
                    }
                }).create().show();
    }

    private void showConvertSuccess() {
        TCLoadingDataView.dismiss();
        new androidx.appcompat.app.AlertDialog.Builder(this)
                .setTitle(R.string.op_wallet_convert_success)
                .setCancelable(false)
                .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        finishAffinity();
                    }
                }).create().show();
    }

    //检查蓝牙权限
    @AfterPermissionGranted(EasyPermissionUtils.PERMISSION_REQUEST_CODE_LOCATION)
    private void checkBltPermission() {
        //检查是否有蓝牙
        if (!BleManager.getInstance().isSupportBle()) {

            new AlertDialog.Builder(this).setTitle(R.string.common_text_hint).setMessage(R.string.common_text_bluetooth_not_support)
                    .setCancelable(false).setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    finish();
                }
            }).show();
            return;
        }


        if (!EasyPermissionUtils.checkLocationPermission()) {
            EasyPermissionUtils.requestLocationPermission(this);
        } else {
            //检查蓝牙是否打开
            if (!BleManager.getInstance().isBlueEnable()) {
                new AlertDialog.Builder(this).setTitle(R.string.common_text_hint).setMessage(R.string.common_text_please_open_bluetooth)
                        .setPositiveButton(R.string.common_text_confirm, new DialogInterface.OnClickListener() {
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                                startActivityForResult(intent, 100);
                            }
                        }).show();

                //this.startActivity(new Intent(Settings.ACTION_BLUETOOTH_SETTINGS));

            }
        }
    }


    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 100) {
            checkBltPermission();
        }
    }

    /**
     * 初始化蓝牙设备
     */
    private void initAcsDevice() {

        /* Initialize mBluetoothReaderManager. */
        mAcsBluetoothReaderManager = new BluetoothReaderManager();

        /* Register BluetoothReaderManager's listeners */
        mAcsBluetoothReaderManager
                .setOnReaderDetectionListener(new BluetoothReaderManager.OnReaderDetectionListener() {

                    @Override
                    public void onReaderDetection(BluetoothReader reader) {

                        if (reader instanceof Acr3901us1Reader) {
                            /* The connected reader is ACR3901U-S1 reader. */
                            Log.v(TAG, "On Acr3901us1Reader Detected.");
                        } else if (reader instanceof Acr1255uj1Reader) {
                            /* The connected reader is ACR1255U-J1 reader. */
                            Log.v(TAG, "On Acr1255uj1Reader Detected.");
                        } else {
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    Toast.makeText(BleNfcMessageActivity.this,
                                            "The device is not supported!",
                                            Toast.LENGTH_SHORT).show();
                                    showNfcConnectFail();

                                    /* Disconnect Bluetooth reader */
                                    Log.v(TAG, "Disconnect reader!!!");
                                    disconnectReader();
                                }
                            });
                            return;
                        }

                        mAcsBluetoothReader = reader;
                        setAcsDeviceListener();
                        setApduExecuteListener();
                        activateReader(reader);
                    }
                });
        /* Initialize BluetoothReaderGattCallback. */
        mAcsGattCallback = new BluetoothReaderGattCallback();

        /* Register BluetoothReaderGattCallback's listeners */
        mAcsGattCallback
                .setOnConnectionStateChangeListener(new BluetoothReaderGattCallback.OnConnectionStateChangeListener() {

                    @Override
                    public void onConnectionStateChange(
                            final BluetoothGatt gatt, final int state,
                            final int newState) {

                        if (state != BluetoothGatt.GATT_SUCCESS) {
                            /*
                             * Show the message on fail to
                             * connect/disconnect.
                             */
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    showBleConnectFail();
                                }
                            });
                            return;
                        }

                        if (newState == BluetoothProfile.STATE_CONNECTED) {
                            /* Detect the connected reader. */
//                            runOnUiThread(new Runnable() {
//                                @Override
//                                public void run() {
////                                    dismissLoading();
//                                    tvReconnect.setVisibility(View.GONE);
////                                    ToastUtil.showToast(BleNfcMessageActivity.this, R.string.common_text_bluetooth_connect_success);
//                                }
//                            });
                            if (mAcsBluetoothReaderManager != null) {
                                mAcsBluetoothReaderManager.detectReader(
                                        gatt, mAcsGattCallback);
                            }
                        } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                            mAcsBluetoothReader = null;
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    showBleConnectFail();
                                }
                            });
                            /*
                             * Release resources occupied by Bluetooth
                             * GATT client.
                             */
                            if (mAcsBluetoothGatt != null) {
                                mAcsBluetoothGatt.close();
                                mAcsBluetoothGatt = null;
                            }
                        }
                    }
                });
    }

    /*
     * Create a GATT connection with the reader. And detect the connected reader
     * once service list is available.
     */
    private boolean connectAcsReader() {
        BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        if (bluetoothManager == null) {
            Log.w(TAG, "Unable to initialize BluetoothManager.");
            showBleConnectFail();
            return false;
        }

        BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
        if (bluetoothAdapter == null) {
            Log.w(TAG, "Unable to obtain a BluetoothAdapter.");
            showBleConnectFail();
            return false;
        }

        /*
         * Connect Device.
         */
        /* Clear old GATT connection. */
        if (mAcsBluetoothGatt != null) {
            Log.i(TAG, "Clear old GATT connection");
            mAcsBluetoothGatt.disconnect();
            mAcsBluetoothGatt.close();
            mAcsBluetoothGatt = null;
        }

        /* Create a new connection. */
        final BluetoothDevice device = bluetoothAdapter
                .getRemoteDevice(bleDevice.getDevice().getAddress());

        if (device == null) {
            Log.w(TAG, "Device not found. Unable to connect.");
            showBleConnectFail();
            return false;
        }

        /* Connect to GATT server. */
        showBleConnecting();
        mAcsBluetoothGatt = device.connectGatt(this, false, mAcsGattCallback);
        return true;
    }

    /* Disconnects an established connection. */
    private void disconnectReader() {
        if (mAcsBluetoothGatt == null) {
//            updateConnectionState(BluetoothReader.STATE_DISCONNECTED);
            return;
        }
//        updateConnectionState(BluetoothReader.STATE_DISCONNECTING);
        mAcsBluetoothGatt.disconnect();
    }

    /* Start the process to enable the reader's notifications. */
    private void activateReader(BluetoothReader reader) {
        if (reader == null) {
            showBleConnectFail();
            return;
        }

        if (reader instanceof Acr3901us1Reader) {
            /* Start pairing to the reader. */
            ((Acr3901us1Reader) mAcsBluetoothReader).startBonding();
        } else if (mAcsBluetoothReader instanceof Acr1255uj1Reader) {
            /* Enable notification. */
            mAcsBluetoothReader.enableNotification(true);
        }
    }

    /**
     * 设置reader的回调
     */
    private void setAcsDeviceListener() {
        /* 验证的是蓝牙设备，不是nfc卡片，成功后供电，否则中止 */
        mAcsBluetoothReader
                .setOnAuthenticationCompleteListener(new BluetoothReader.OnAuthenticationCompleteListener() {

                    @Override
                    public void onAuthenticationComplete(
                            BluetoothReader bluetoothReader, final int errorCode) {
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (errorCode == BluetoothReader.ERROR_SUCCESS) {
                                    LogUtils.w(TAG, "验证设备成功");
                                    showNfcConnecting();
                                    powerOnCard();
                                } else {
                                    LogUtils.w(TAG, "验证设备失败");
                                    showBleConnectFail();
                                }
                            }
                        });
                    }

                });
        /* 供电成功，表明有nfc卡，传输指令 */
        mAcsBluetoothReader
                .setOnAtrAvailableListener(new BluetoothReader.OnAtrAvailableListener() {

                    @Override
                    public void onAtrAvailable(BluetoothReader bluetoothReader,
                                               final byte[] atr, final int errorCode) {
                        try {
                            Log.w(TAG, "Power on listener " + new String(atr, "UTF-8"));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        if (atr == null) {
                            //继续检测，通电
                            powerOnCard();
                            LogUtils.w(TAG, "Power failed");
                        } else {
                            LogUtils.w(TAG, "Power Success");
                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    showNfcConnectSuccess();
                                    apduMode = APDU_MODE_CHECK_UID;
                                    transmitAPDU(APDU_COMMAND_LOAD_AUTH);
                                }
                            });
                        }
                    }

                });
        mAcsBluetoothReader
                .setOnEnableNotificationCompleteListener(new BluetoothReader.OnEnableNotificationCompleteListener() {

                    @Override
                    public void onEnableNotificationComplete(
                            BluetoothReader bluetoothReader, final int result) {
                        Log.w(TAG, "连接设备success = 0 ? " + result);
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (result != BluetoothGatt.GATT_SUCCESS) {
                                    /* Fail */
//                                    ToastUtils.showShort(
//                                            R.string.nfc_connect_fail_retry);
                                    showNfcConnectFail();
                                } else {
//                                    ToastUtils.showShort(
//                                            R.string.nfc_connect_sucess);
                                    //连接设备成功后，authenticate验证设备
                                    authenticateCard();
                                }
                            }
                        });
                    }

                });

    }

    /**
     * 验证设备秘钥
     * 验证的是设备，而不是是否有卡
     */
    private void authenticateCard() {
        if (mAcsBluetoothReader == null) {
            ToastUtils.showShort("card_reader_not_ready");
            showBleConnectFail();
            return;
        }
        /* Retrieve master key from edit box. */
        try {
            byte[] masterKey = DEFAULT_1255_MASTER_KEY.getBytes(StandardCharsets.UTF_8);
            if (masterKey.length > 0) {
                /* Start authentication. */
                if (!mAcsBluetoothReader.authenticate(masterKey)) {
                    ToastUtils.showShort("card_reader_not_ready");
                    showBleConnectFail();
                } else {
                    Log.d(TAG, "Authenticating...");
                }
            } else {
                ToastUtils.showShort("Character format error!");
                showBleConnectFail();
            }
        } catch (Exception e) {
            e.printStackTrace();
            showBleConnectFail();
        }
    }

    /**
     * 供电, 实则为检测是否有卡片连接
     */
    private void powerOnCard() {
        Log.w(TAG, "开始power on");
        if (mAcsBluetoothReader == null) {
            showBleConnectFail();
            return;
        }
        if (!mAcsBluetoothReader.powerOnCard()) {
            showNfcConnectSuccess();
            apduMode = APDU_MODE_CHECK_UID;
            transmitAPDU(APDU_COMMAND_LOAD_AUTH);
        } else {
            Log.w(TAG, "Powering on...");
        }
    }

}
